package stack;

import java.util.Map;

public class Functions {
    public static void main(String[] args) {

        try {
            int res = evaluate("12-0+4*5+3");
            System.out.println("res = " + res);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

    }

    public static int evaluate(String expression) {
        int size = expression.length();
        ArrayStack numStack = new ArrayStack(size);
        ArrayStack operatorStack = new ArrayStack(size);
        int keepNum = 0;

        for (int i = 0; i < size; i++) {
            char c = expression.charAt(i);
            if(isOperator(c)) { // 运算符
                if (!operatorStack.isEmpty() && priority(c) <= priority(operatorStack.topVal())) {
                    int num1 = numStack.pop();
                    int num2 = numStack.pop();
                    numStack.push(calculate(num1, num2, operatorStack.pop()));
                }
                operatorStack.push(c);
            } else { // 数字
                if (i == size - 1 || isOperator(expression.charAt(i + 1))) {
                    numStack.push(keepNum * 10 + c - 48);
                    keepNum = 0;
                } else {
                    keepNum = keepNum * 10 + c - 48;
                }
            }
        }
        while (!operatorStack.isEmpty()) {
            int num1 = numStack.pop();
            int num2 = numStack.pop();
            numStack.push(calculate(num1, num2, operatorStack.pop()));
        }
        numStack.show();
        return numStack.pop();
    }

    private static boolean isOperator(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/';
    }

    private static int priority(int c) {
        if (c == '+' || c == '-') {
            return 0;
        } else if (c == '*' || c == '/') {
            return 1;
        } else {
            return -1;
        }
    }

    private static int calculate(int num1, int num2, int c) {
        switch (c) {
            case '+':
                return num2 + num1;
            case '-':
                return num2 - num1;
            case '*':
                return num2 * num1;
            case '/':
                return num2 / num1;
        }
        return 0;
    }
}
